package org.jeecg.modules.lab.exam.paper.service.impl;



import com.aliyun.oss.ServiceException;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import org.jeecg.common.system.vo.LoginUser;
import org.jeecg.modules.lab.exam.entity.*;
import org.jeecg.modules.lab.exam.exam.mapper.LabExamRepoMapper;
import org.jeecg.modules.lab.exam.paper.mapper.LabExamPaperMapper;
import org.jeecg.modules.lab.exam.paper.mapper.LabExamPaperQuestionAnswerMapper;
import org.jeecg.modules.lab.exam.paper.mapper.LabExamPaperQuestionMapper;
import org.jeecg.modules.lab.exam.paper.service.ILabExamPaperQuestionAnswerService;
import org.jeecg.modules.lab.exam.paper.service.ILabExamPaperQuestionService;
import org.jeecg.modules.lab.exam.paper.service.ILabExamPaperService;
import org.jeecg.modules.lab.exam.question.mapper.LabExamQuestionAnswerMapper;
import org.jeecg.modules.lab.exam.question.mapper.LabExamQuestionMapper;
import org.springframework.stereotype.Service;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.io.Serializable;
import java.util.*;

/**
 * @Description: 考试记录
 * @Author: jeecg-boot
 * @Date:   2023-08-30
 * @Version: V1.0
 */
@Service
public class LabExamPaperServiceImpl extends ServiceImpl<LabExamPaperMapper, LabExamPaper> implements ILabExamPaperService {

	@Autowired
	private LabExamPaperMapper labExamPaperMapper;
	@Autowired
	private LabExamPaperQuestionMapper labExamPaperQuestionMapper;
	@Autowired
	private LabExamPaperQuestionAnswerMapper labExamPaperQuestionAnswerMapper;
	@Autowired
	private LabExamRepoMapper labExamRepoMapper;
	@Autowired
	private LabExamQuestionMapper labExamQuestionMapper;
	@Autowired
	private LabExamQuestionAnswerMapper labExamQuestionAnswerMapper;
	@Autowired
	private ILabExamPaperQuestionService labExamPaperQuestionService;
	@Autowired
	private ILabExamPaperQuestionAnswerService labExamPaperQuestionAnswerService;

	
	@Override
	@Transactional(rollbackFor = Exception.class)
	public void saveMain(LabExamPaper labExamPaper, List<LabExamPaperQuestion> labExamPaperQuestionList, List<LabExamPaperQuestionAnswer> labExamPaperQuestionAnswerList) {
		labExamPaperMapper.insert(labExamPaper);
		if(labExamPaperQuestionList!=null && labExamPaperQuestionList.size()>0) {
			for(LabExamPaperQuestion entity:labExamPaperQuestionList) {
				//外键设置
				entity.setPaperId(labExamPaper.getId());
				labExamPaperQuestionMapper.insert(entity);
			}
		}
		if(labExamPaperQuestionAnswerList!=null && labExamPaperQuestionAnswerList.size()>0) {
			for(LabExamPaperQuestionAnswer entity:labExamPaperQuestionAnswerList) {
				//外键设置
				entity.setPaperId(labExamPaper.getId());
				labExamPaperQuestionAnswerMapper.insert(entity);
			}
		}
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public void updateMain(LabExamPaper labExamPaper,List<LabExamPaperQuestion> labExamPaperQuestionList,List<LabExamPaperQuestionAnswer> labExamPaperQuestionAnswerList) {
		labExamPaperMapper.updateById(labExamPaper);
		
		//1.先删除子表数据
		labExamPaperQuestionMapper.deleteByMainId(labExamPaper.getId());
		labExamPaperQuestionAnswerMapper.deleteByMainId(labExamPaper.getId());
		
		//2.子表数据重新插入
		if(labExamPaperQuestionList!=null && labExamPaperQuestionList.size()>0) {
			for(LabExamPaperQuestion entity:labExamPaperQuestionList) {
				//外键设置
				entity.setPaperId(labExamPaper.getId());
				labExamPaperQuestionMapper.insert(entity);
			}
		}
		if(labExamPaperQuestionAnswerList!=null && labExamPaperQuestionAnswerList.size()>0) {
			for(LabExamPaperQuestionAnswer entity:labExamPaperQuestionAnswerList) {
				//外键设置
				entity.setPaperId(labExamPaper.getId());
				labExamPaperQuestionAnswerMapper.insert(entity);
			}
		}
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public void delMain(String id) {
		labExamPaperQuestionMapper.deleteByMainId(id);
		labExamPaperQuestionAnswerMapper.deleteByMainId(id);
		labExamPaperMapper.deleteById(id);
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public void delBatchMain(Collection<? extends Serializable> idList) {
		for(Serializable id:idList) {
			labExamPaperQuestionMapper.deleteByMainId(id.toString());
			labExamPaperQuestionAnswerMapper.deleteByMainId(id.toString());
			labExamPaperMapper.deleteById(id);
		}
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public String creatPaper(LoginUser sysUser, LabExam labExam) {


		QueryWrapper<LabExamPaper> wrapper = new QueryWrapper<>();
		wrapper.lambda()
				.eq(LabExamPaper::getUserId, sysUser.getId())
				.eq(LabExamPaper::getState, "考试中")
				.eq(LabExamPaper::getExamId, labExam.getId());

		int exists = (int) this.count(wrapper);


		if (exists > 0) {
			throw new ServiceException("您有正在进行的考试！");
		}

		// 判断考试
		if(labExam == null){
			throw new ServiceException("考试不存在！");
		}

		if(!"开放中".equals(labExam.getStatus())){
			throw new ServiceException("考试状态不正确！");
		}

		// 考试题目列表
		List<LabExamPaperQuestion> quList = this.generateByQuestion(labExam.getId());

		if(CollectionUtils.isEmpty(quList)){
			throw new ServiceException("规则不正确，无对应的考题！");
		}

		//保存试卷内容
		LabExamPaper paper = this.savePaper(sysUser,labExam, quList);

		// 强制交卷任务
//		String jobName = "break_exam_" + paper.getId();
//		jobService.addCronJob(BreakExamJob.class, jobName, CronUtils.dateToCron(paper.getLimitTime()), paper.getId());

		return paper.getId();
	}



	public List<LabExamPaperQuestion> generateByQuestion(String examId){
		// 查找规则指定的题库
		List<LabExamRepo> list = labExamRepoMapper.selectByMainId(examId);

		//最终的题目列表
		List<LabExamPaperQuestion> quList = new ArrayList<>();

		//排除ID，避免题目重复
		List<String> excludes = new ArrayList<>();
		excludes.add("none");
		QueryWrapper<LabExamQuestion> wrapper = new QueryWrapper<>();
		if (!CollectionUtils.isEmpty(list)) {
			for (LabExamRepo item : list) {
				// 单选题
				if(item.getRadioCount() > 0){
					wrapper.clear();
					wrapper.eq("bank_Id",item.getBankId());
					wrapper.eq("type","单选题");
					wrapper.last("limit "+item.getRadioCount());
					List<LabExamQuestion> radioList = labExamQuestionMapper.selectList(wrapper);
					for (LabExamQuestion qu : radioList) {
						LabExamPaperQuestion paperQu = new LabExamPaperQuestion();
						paperQu.setQuestionId(qu.getId());
						paperQu.setQuestionType(qu.getType());
						paperQu.setContent(qu.getContent());
						paperQu.setScore(item.getRadioScore());
						paperQu.setRightAnswer(qu.getAnswer());
						paperQu.setAnswered("0");
						quList.add(paperQu);
						excludes.add(qu.getId());
					}
				}

				//多选题
				if(item.getMultiCount() > 0) {
					wrapper.clear();
					wrapper.eq("bank_Id",item.getBankId());
					wrapper.eq("type","多选题");
					wrapper.last("limit "+item.getMultiCount());
					List<LabExamQuestion> multiList = labExamQuestionMapper.selectList(wrapper);
					for (LabExamQuestion qu : multiList) {
						LabExamPaperQuestion paperQu = new LabExamPaperQuestion();
						paperQu.setQuestionId(qu.getId());
						paperQu.setQuestionType(qu.getType());
						paperQu.setContent(qu.getContent());
						paperQu.setScore(item.getMultiScore());
						paperQu.setRightAnswer(qu.getAnswer());
						paperQu.setAnswered("0");
						quList.add(paperQu);
						excludes.add(qu.getId());
					}
				}

				// 判断题
				if(item.getJudgeCount() > 0) {
					wrapper.clear();
					wrapper.eq("bank_Id",item.getBankId());
					wrapper.eq("type","判断题");
					wrapper.last("limit "+item.getJudgeCount());
					List<LabExamQuestion> judgeList = labExamQuestionMapper.selectList(wrapper);
					for (LabExamQuestion qu : judgeList) {
						LabExamPaperQuestion paperQu = new LabExamPaperQuestion();
						paperQu.setQuestionId(qu.getId());
						paperQu.setQuestionType(qu.getType());
						paperQu.setContent(qu.getContent());
						paperQu.setScore(item.getJudgeScore());
						paperQu.setRightAnswer(qu.getAnswer());
						paperQu.setAnswered("0");
						quList.add(paperQu);
						excludes.add(qu.getId());
					}
				}
			}
		}
		return quList;
	}

	/**
	 * 保存试卷
	 * @param sysUser
	 * @param labExam
	 * @param quList
	 * @return
	 */
	private LabExamPaper savePaper(LoginUser sysUser, LabExam labExam, List<LabExamPaperQuestion> quList) {


		//保存试卷基本信息
		LabExamPaper paper = new LabExamPaper();
		paper.setUserId(sysUser.getId());
		paper.setUserName(sysUser.getUsername());
		paper.setDepartId(sysUser.getDepartIds());
		paper.setExamId(labExam.getId());
		paper.setExamTitle(labExam.getName());
		paper.setExamTime(labExam.getTotalTime());
		paper.setExamScore(labExam.getTotalScore());
		paper.setPassScore(labExam.getPassScore());
		paper.setState("考试中");
		paper.setUserScore(0.00);

		// 截止时间
		if(labExam.getTotalTime() !=null && labExam.getTotalTime()>0){
			Calendar cl = Calendar.getInstance();
			cl.setTimeInMillis(System.currentTimeMillis());
			cl.add(Calendar.MINUTE, labExam.getTotalTime());
			paper.setLimitTime(cl.getTime());
		}
		labExamPaperMapper.insert(paper);

		if (!CollectionUtils.isEmpty(quList)) {
			this.savePaperQu(paper.getId(), quList);
		}

		return paper;
	}

	/**
	 * 保存试卷试题列表
	 * @param paperId
	 * @param quList
	 */
	private void savePaperQu(String paperId, List<LabExamPaperQuestion> quList){

		List<LabExamPaperQuestion> batchQuList = new ArrayList<>();
		List<LabExamPaperQuestionAnswer> batchAnswerList = new ArrayList<>();

		int sort = 0;
		for (LabExamPaperQuestion item : quList) {

			item.setPaperId(paperId);
			item.setSort(sort);
			item.setId(IdWorker.getIdStr());

			//回答列表
			List<LabExamQuestionAnswer> answerList = labExamQuestionAnswerMapper.selectByMainId(item.getQuestionId());

			if (!CollectionUtils.isEmpty(answerList)) {

				int ii = 0;
				for (LabExamQuestionAnswer answer : answerList) {
					LabExamPaperQuestionAnswer paperQuAnswer = new LabExamPaperQuestionAnswer();
					paperQuAnswer.setPaperId(paperId);
					paperQuAnswer.setQuestionId(item.getQuestionId());
					paperQuAnswer.setAnswerId(answer.getId());
					paperQuAnswer.setContent(answer.getContent());
					paperQuAnswer.setChecked("0");
					paperQuAnswer.setSort(ii);
					paperQuAnswer.setIsRight(answer.getIsRight());
					ii++;
					batchAnswerList.add(paperQuAnswer);
				}
			}

			batchQuList.add(item);
			sort++;
		}

		//添加问题
		labExamPaperQuestionService.saveBatch(batchQuList);

		//批量添加问题答案
		labExamPaperQuestionAnswerService.saveBatch(batchAnswerList);
	}


	@Override
	public double submitPaper(String paperId) {
		//计算本次考试得分
		double score =countPaperScore(paperId);
		//根据本次考试状态和分数
		LabExamPaper labExamPaper =labExamPaperMapper.selectById(paperId);
		labExamPaper.setUserScore(score);
		labExamPaper.setState("已结束");
		labExamPaper.setSynFlag("1");
		labExamPaperMapper.updateById(labExamPaper);
		return score;
	}

	public double countPaperScore(String paperId){
		double actualScore=0.00;

		List<LabExamPaperQuestion> labExamPaperQuestions =  labExamPaperQuestionMapper.selectByMainId(paperId);
		for (int i=0;i<labExamPaperQuestions.size();i++){
			LabExamPaperQuestion question = labExamPaperQuestions.get(i);
			String quId =question.getQuestionId();
			String anId =question.getAnswer();
			String quType =question.getQuestionType();
			double score = 0.00;
			if(question.getScore() != null){
				score =question.getScore();
			}
			if(quType.equals("单选题") || quType.equals("判断题")){
				LabExamPaperQuestionAnswer answer = labExamPaperQuestionAnswerMapper.selectById(anId);
				if(answer.getIsRight().equals("true")){
					question.setActualScore(score);
					question.setIsRight("正确");
				}else {
					question.setActualScore(0);
					question.setIsRight("错误");
				}
				labExamPaperQuestionMapper.updateById(question);
				actualScore = actualScore + question.getActualScore();
			}else{
				//多选题
				//已选中的答案
				QueryWrapper<LabExamPaperQuestionAnswer> wrapper = new QueryWrapper<>();
				wrapper.eq("question_id",quId);
				wrapper.eq("paper_id",paperId);
				wrapper.eq("checked","1");
				List<LabExamPaperQuestionAnswer> answerList =labExamPaperQuestionAnswerMapper.selectList(wrapper);
				wrapper.clear();
				wrapper.eq("question_id",quId);
				wrapper.eq("paper_id",paperId);
				wrapper.eq("is_right","true");
				//正确答案的个数
				long amount = labExamPaperQuestionAnswerMapper.selectCount(wrapper);

				for(int z=0;z<answerList.size();z++){
					LabExamPaperQuestionAnswer answer =answerList.get(z);
					String isRight =answer.getIsRight();
					//有一个答案是错的，该题就是错误，得0分
					if(isRight.equals("false")){
						question.setActualScore(0);
						question.setIsRight("错误");
						break;
					}
				}

				if("错误".equals(question.getIsRight())){
					labExamPaperQuestionMapper.updateById(question);
				}else{
					if(amount == answerList.size()){
						question.setActualScore(score);
						question.setIsRight("正确");
						labExamPaperQuestionMapper.updateById(question);
					}else{
						question.setActualScore((score/2));
						labExamPaperQuestionMapper.updateById(question);
					}
					actualScore = actualScore + question.getActualScore();
				}
			}
		}
		return actualScore;
	}


}
